SRC_PATH = src/core
ALGO_SRC_PATH = $(SRC_PATH)/algorithms
UTIL_INCLUDES = $(SRC_PATH)/File.h $(SRC_PATH)/Process.h

BIN_PATH = bin
OBJ_PATH = $(BIN_PATH)/*/obj 
OBJ_RELEASE_PATH = $(BIN_PATH)/release/obj
OBJ_DEBUG_PATH = $(BIN_PATH)/debug/obj

RELEASE_PATH = $(BIN_PATH)/release
DEBUG_PATH = $(BIN_PATH)/debug

GUI_SRC_PATH = src/gui/org/fsdeduplicator
GUI_PACKAGE_NAME = org/fsdeduplicator
GUI_CLASS_PATH = $(BIN_PATH)/*/gui/$(GUI_PACKAGE_NAME)
GUI_RELEASE_PATH = $(RELEASE_PATH)/gui
GUI_DEBUG_PATH = $(DEBUG_PATH)/gui
GUI_ENTRY_POINT = org.fsdeduplicator.FileDedupe

ALGO_RELEASE_OBJECTS = $(OBJ_RELEASE_PATH)/MD5Algorithm.o $(OBJ_RELEASE_PATH)/MD4Algorithm.o \
                       $(OBJ_RELEASE_PATH)/LCSAlgorithm.o $(OBJ_RELEASE_PATH)/LevenshteinAlgorithm.o \
                       $(OBJ_RELEASE_PATH)/HistComparisonAlgorithm.o $(OBJ_RELEASE_PATH)/SelectorAlgorithm.o

RELEASE_OBJECTS = $(OBJ_RELEASE_PATH)/main.o $(OBJ_RELEASE_PATH)/FileDedupe.o \
                  $(OBJ_RELEASE_PATH)/FilesystemReader.o $(OBJ_RELEASE_PATH)/CompositeFilter.o \
                  $(OBJ_RELEASE_PATH)/Executor.o $(OBJ_RELEASE_PATH)/EqualityFilter.o \
                  $(OBJ_RELEASE_PATH)/SizeFilter.o $(OBJ_RELEASE_PATH)/FormatFilter.o \
                  $(OBJ_RELEASE_PATH)/FormatQualifier.o $(OBJ_RELEASE_PATH)/ConfigParser.o \
                  $(OBJ_RELEASE_PATH)/Printer.o $(OBJ_RELEASE_PATH)/TaskLauncher.o \
		  $(OBJ_RELEASE_PATH)/configuration.o \
		  $(ALGO_RELEASE_OBJECTS)

ALGO_DEBUG_OBJECTS = $(OBJ_DEBUG_PATH)/MD5Algorithm.o $(OBJ_DEBUG_PATH)/MD4Algorithm.o \
                     $(OBJ_DEBUG_PATH)/LCSAlgorithm.o $(OBJ_DEBUG_PATH)/LevenshteinAlgorithm.o \
                     $(OBJ_DEBUG_PATH)/HistComparisonAlgorithm.o $(OBJ_DEBUG_PATH)/SelectorAlgorithm.o

DEBUG_OBJECTS = $(OBJ_DEBUG_PATH)/main.o $(OBJ_DEBUG_PATH)/FileDedupe.o \
                $(OBJ_DEBUG_PATH)/FilesystemReader.o $(OBJ_DEBUG_PATH)/CompositeFilter.o \
                $(OBJ_DEBUG_PATH)/Executor.o $(OBJ_DEBUG_PATH)/EqualityFilter.o \
                $(OBJ_DEBUG_PATH)/SizeFilter.o $(OBJ_DEBUG_PATH)/FormatFilter.o \
                $(OBJ_DEBUG_PATH)/FormatQualifier.o $(OBJ_DEBUG_PATH)/ConfigParser.o \
                $(OBJ_DEBUG_PATH)/Printer.o $(OBJ_DEBUG_PATH)/TaskLauncher.o \
		$(OBJ_DEBUG_PATH)/configuration.o \
		$(ALGO_DEBUG_OBJECTS)

CPP = g++

CFLAGS = -Wall -O2 -std=c++11 `pkg-config opencv --cflags`
LFLAGS = -L/opt/local/lib/ -lboost_filesystem -lboost_system -lboost_program_options -lcrypto `pkg-config opencv --libs`

.PHONY: release
release: $(RELEASE_PATH)/fsdedupe $(GUI_RELEASE_PATH)/fsdedupe.jar

.PHONY: debug
debug: CFLAGS = -Wall -O0 -std=c++11 -ggdb -DDEBUG `pkg-config opencv --cflags`
debug: $(DEBUG_PATH)/fsdedupe $(GUI_DEBUG_PATH)/fsdedupe.jar

# Targets for debug build configuration

$(DEBUG_PATH)/fsdedupe: $(DEBUG_OBJECTS) 
	$(CPP) $(DEBUG_OBJECTS) -o $(DEBUG_PATH)/fsdedupe $(LFLAGS)

$(OBJ_DEBUG_PATH)/main.o: $(SRC_PATH)/main.cpp $(SRC_PATH)/*.h\
	$(ALGO_SRC_PATH)/*.h

	$(CPP) $(CFLAGS) -c $< -o $@

$(OBJ_DEBUG_PATH)/FileDedupe.o: $(SRC_PATH)/FileDedupe.cpp $(SRC_PATH)/*.h \
	$(ALGO_SRC_PATH)/*.h

	$(CPP) $(CFLAGS) -c $< -o $@

$(OBJ_DEBUG_PATH)/ConfigParser.o: $(SRC_PATH)/ConfigParser.cpp \
				  $(SRC_PATH)/ConfigParser.h

	$(CPP) $(CFLAGS) -c $< -o $@

$(OBJ_DEBUG_PATH)/%.o: $(ALGO_SRC_PATH)/%.cpp $(ALGO_SRC_PATH)/*.h  
	$(CPP) $(CFLAGS) -c $< -o $@

$(OBJ_DEBUG_PATH)/%.o: $(ALGO_SRC_PATH)/img/%.cpp $(ALGO_SRC_PATH)/img/*.h $(ALGO_SRC_PATH)/*.h
	$(CPP) $(CFLAGS) -c $< -o $@

$(OBJ_DEBUG_PATH)/%.o: $(SRC_PATH)/%.cpp $(SRC_PATH)/*.h $(ALGO_SRC_PATH)/*.h $(ALGO_SRC_PATH)/img/*.h
	$(CPP) $(CFLAGS) -c $< -o $@


# Targets for release build configuration

$(RELEASE_PATH)/fsdedupe: $(RELEASE_OBJECTS) 
	$(CPP) $(RELEASE_OBJECTS) -o $(RELEASE_PATH)/fsdedupe $(LFLAGS)

$(OBJ_RELEASE_PATH)/main.o: $(SRC_PATH)/main.cpp $(SRC_PATH)/*.h\
	$(ALGO_SRC_PATH)/*.h

	$(CPP) $(CFLAGS) -c $< -o $@

$(OBJ_RELEASE_PATH)/FileDedupe.o: $(SRC_PATH)/FileDedupe.cpp $(SRC_PATH)/*.h \
	$(ALGO_SRC_PATH)/*.h

	$(CPP) $(CFLAGS) -c $< -o $@

$(OBJ_RELEASE_PATH)/ConfigParser.o: $(SRC_PATH)/ConfigParser.cpp \
				    $(SRC_PATH)/ConfigParser.h
	$(CPP) $(CFLAGS) -c $< -o $@

$(OBJ_RELEASE_PATH)/%.o: $(ALGO_SRC_PATH)/%.cpp $(ALGO_SRC_PATH)/*.h  
	$(CPP) $(CFLAGS) -c $< -o $@

$(OBJ_RELEASE_PATH)/%.o: $(ALGO_SRC_PATH)/img/%.cpp $(ALGO_SRC_PATH)/img/*.h $(ALGO_SRC_PATH)/*.h
	$(CPP) $(CFLAGS) -c $< -o $@

$(OBJ_RELEASE_PATH)/%.o: $(SRC_PATH)/%.cpp $(SRC_PATH)/*.h $(ALGO_SRC_PATH)/*.h $(ALGO_SRC_PATH)/img/*.h
	$(CPP) $(CFLAGS) -c $< -o $@

$(GUI_RELEASE_PATH)/fsdedupe.jar: $(GUI_SRC_PATH)/*.java
	javac -d $(GUI_RELEASE_PATH) $(GUI_SRC_PATH)/*.java
	jar cfe $(GUI_RELEASE_PATH)/fsdedupe.jar $(GUI_ENTRY_POINT) -C $(GUI_RELEASE_PATH) org

$(GUI_DEBUG_PATH)/fsdedupe.jar: $(GUI_SRC_PATH)/*.java
	javac -d $(GUI_DEBUG_PATH) $(GUI_SRC_PATH)/*.java
	jar cfe $(GUI_DEBUG_PATH)/fsdedupe.jar $(GUI_ENTRY_POINT) -C $(GUI_DEBUG_PATH) org

clean:
	rm -rf $(OBJ_RELEASE_PATH)/*.o $(OBJ_DEBUG_PATH)/*.o $(BIN_PATH)/*/fsdedupe \
	    $(GUI_CLASS_PATH)/*.class $(BIN_PATH)/*/*/fsdedupe.jar

